/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl.section;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.encrypt.utils.EncryptUtils;
import com.comac.ins.isfd.constant.enums.IsfdSectionTypeEnum;
import com.comac.ins.isfd.domain.IsfdSection;
import com.comac.ins.isfd.domain.IsfdSectionResult;
import com.comac.ins.isfd.domain.bo.IsfdSectionBo;
import com.comac.ins.isfd.domain.vo.IsfdLayupEquivalentMaterialVo;
import com.comac.ins.isfd.util.SectionCalculateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 型材库 帽型长桁结构 实现类
 *
 * @author hxloongs
 * @date 2024-7-30
 */
@Service
public class IsfdSectionCapServiceImpl extends IsfdAbstractSectionService {
    @Override
    public String selectByType() {
        return IsfdSectionTypeEnum.CAP.getValue();
    }

    @Override
    public double[] calculate(IsfdSectionBo isfdSectionBo) {
        String epLayerCode = isfdSectionBo.getEpLayerCode();

        IsfdLayupEquivalentMaterialVo isfdLayupEquivalentMaterialVo = iIsfdLayupEquivalentMaterialService.queryByLayCode(epLayerCode);
        // 查询铺层库的代码，填充T E G 和 rho 、thm
        double[] layerParametersCap = {isfdLayupEquivalentMaterialVo.getT(), isfdLayupEquivalentMaterialVo.getExx(), isfdLayupEquivalentMaterialVo.getGxy()}; // T, E, G
        double[] shapeParametersCap = {isfdSectionBo.getAlpha(), isfdSectionBo.getD(), isfdSectionBo.getH(), isfdSectionBo.getL(), isfdSectionBo.getR1(), isfdSectionBo.getR2()}; // ALPHA, D, H, L, R1, R2
        double[] sectionPropertiesCap = new double[8]; // E, G, XC, A, I1, I2
        SectionCalculateUtils.calculateCapProfile(layerParametersCap, shapeParametersCap, sectionPropertiesCap);
        sectionPropertiesCap[6] = isfdLayupEquivalentMaterialVo.getRho(); // rho
        sectionPropertiesCap[7] = isfdLayupEquivalentMaterialVo.getX(); // thm
        return sectionPropertiesCap;
    }

    @Override
    public String generateSerialNumber(IsfdSectionBo bo) {
        // 1. 参数校验
        checkBaseParams(bo);
        // 2. 生成型材编码
        // 编号规则：“CAP”+自定义编号
        // 自定义编号 = ep铺层代号 + H + 右补齐8位且自增
        String epLayerCode = bo.getEpLayerCode();
        int h = bo.getH().intValue();
        String preAttributeNumber = epLayerCode + h;
        String attributeNumber = super.geAttributeNumber(preAttributeNumber);
        return IsfdSectionTypeEnum.CAP.getValue() + attributeNumber;
    }

    @Transactional
    @Override
    public Boolean save(IsfdSectionBo bo) {
        // 1. 参数校验
        checkBaseParams(bo);
        checkParams(bo);

        // 2. 获取hash字段
        String hashUniqueKey = EncryptUtils.hashFields(bo.getType(), bo.getSerialNumber(), bo.getAttributeNumber(), bo.getMat1Id(),
            bo.getAlpha(), bo.getD(), bo.getH(), bo.getL(), bo.getR1(), bo.getR2(), bo.getEpLayerCode());

        // 3. 幂等校验
        Boolean isUpdate = super.checkUnique(bo, hashUniqueKey);

        // 4. 计算 计算帽型长桁属性
        double[] sectionPropertiesCap = this.calculate(bo);

        // 5. 落表
        IsfdSection isfdSection = MapstructUtils.convert(bo, IsfdSection.class);
        isfdSection.setHashUniqueKey(hashUniqueKey);
        isfdSection.setRho(sectionPropertiesCap[6]);
        isfdSection.setThm(sectionPropertiesCap[7]);
        // 判断是新增业务还是修改业务，处理落表的方式不同
        if (isUpdate) {
            isfdSectionMapper.updateById(isfdSection);
            IsfdSectionResult isfdSectionResult = isfdSectionResultMapper.selectOne(new LambdaQueryWrapper<IsfdSectionResult>()
                .eq(IsfdSectionResult::getSecId, isfdSection.getId()));
            if (isfdSectionResult == null) {
                throw new BaseException("修改时，发现对应结果记录不存在，请确认后重试！");
            }
            isfdSectionResult.setE(sectionPropertiesCap[0]);
            isfdSectionResult.setG(sectionPropertiesCap[1]);
            isfdSectionResult.setXc(sectionPropertiesCap[2]);
            isfdSectionResult.setA(sectionPropertiesCap[3]);
            isfdSectionResult.setI1(sectionPropertiesCap[4]);
            isfdSectionResult.setI2(sectionPropertiesCap[5]);
            isfdSectionResultMapper.updateById(isfdSectionResult);
        } else {
            isfdSectionMapper.insert(isfdSection);
            IsfdSectionResult isfdSectionResult = new IsfdSectionResult();
            isfdSectionResult.setSecId(isfdSection.getId());
            isfdSectionResult.setE(sectionPropertiesCap[0]);
            isfdSectionResult.setG(sectionPropertiesCap[1]);
            isfdSectionResult.setXc(sectionPropertiesCap[2]);
            isfdSectionResult.setA(sectionPropertiesCap[3]);
            isfdSectionResult.setI1(sectionPropertiesCap[4]);
            isfdSectionResult.setI2(sectionPropertiesCap[5]);
            isfdSectionResultMapper.insert(isfdSectionResult);
        }
        return Boolean.TRUE;
    }


    private void checkBaseParams(IsfdSectionBo isfdSectionBo) {
        if (isfdSectionBo.getAlpha() == null) {
            throw new BaseException("alpha(度)不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getD() == null) {
            throw new BaseException("d不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getH() == null) {
            throw new BaseException("h不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getL() == null) {
            throw new BaseException("l不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getR1() == null) {
            throw new BaseException("r1不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getR2() == null) {
            throw new BaseException("r2不能为空，请确认后重试！");
        }
        if (StringUtils.isBlank(isfdSectionBo.getEpLayerCode())) {
            throw new BaseException("ep铺层代号不能为空，请确认后重试！");
        }
    }

    private void checkParams(IsfdSectionBo isfdSectionBo) {
        if (StringUtils.isBlank(isfdSectionBo.getSerialNumber()) || !isfdSectionBo.getSerialNumber().startsWith(IsfdSectionTypeEnum.CAP.getValue())) {
            throw new BaseException("编号不能为空或者格式不正确（需要CAP开头），请确认后重试！");
        }
        // 重新设置属性号和mat1_ID
        // 属性号 和 MATI_ID 是相同的；
        // 属性号 型材的物理特征，取值根据 型材编号规则产生，把型材编号的前缀类型字段替换掉，剩余的后缀就是属性号。
        // 属性号 最终小于等于8位，且全局唯一
        String serialNumber = isfdSectionBo.getSerialNumber();
        String attributeNumber = serialNumber.replace(IsfdSectionTypeEnum.CAP.getValue(), "");
        isfdSectionBo.setAttributeNumber(attributeNumber);
        isfdSectionBo.setMat1Id(attributeNumber);
    }
}
